#!/usr/bin/env python

# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

import json
from typing import TYPE_CHECKING, Any, Dict

import httpretty

from appium import webdriver
from appium.options.android import UiAutomator2Options
from appium.options.ios import XCUITestOptions
from test.helpers.constants import SERVER_URL_BASE

if TYPE_CHECKING:
    from httpretty.core import HTTPrettyRequestEmpty

    from appium.webdriver.webdriver import WebDriver


def appium_command(command: str) -> str:
    """Return a command of Appium

    Returns:
        str: A string of command URL
    """
    return (
        f'{SERVER_URL_BASE}{command}'
        if SERVER_URL_BASE.endswith('/') or command.startswith('/')
        else f'{SERVER_URL_BASE}/{command}'
    )


def android_w3c_driver() -> 'WebDriver':
    """Return a W3C driver which is generated by a mock response for Android

    Returns:
        `webdriver.webdriver.WebDriver`: An instance of WebDriver
    """

    response_body_json = json.dumps(
        {
            'sessionId': '1234567890',
            'capabilities': {
                'platform': 'LINUX',
                'desired': {
                    'platformName': 'Android',
                    'automationName': 'uiautomator2',
                    'platformVersion': '7.1.1',
                    'deviceName': 'Android Emulator',
                    'app': '/test/apps/ApiDemos-debug.apk',
                },
                'platformName': 'Android',
                'automationName': 'uiautomator2',
                'platformVersion': '7.1.1',
                'deviceName': 'emulator-5554',
                'app': '/test/apps/ApiDemos-debug.apk',
                'deviceUDID': 'emulator-5554',
                'appPackage': 'io.appium.android.apis',
                'appWaitPackage': 'io.appium.android.apis',
                'appActivity': 'io.appium.android.apis.ApiDemos',
                'appWaitActivity': 'io.appium.android.apis.ApiDemos',
            },
        }
    )

    httpretty.register_uri(httpretty.POST, appium_command('/session'), body=response_body_json)

    desired_caps = {
        'platformName': 'Android',
        'deviceName': 'Android Emulator',
        'app': 'path/to/app',
        'automationName': 'UIAutomator2',
    }

    driver = webdriver.Remote(SERVER_URL_BASE, options=UiAutomator2Options().load_capabilities(desired_caps))
    return driver


def ios_w3c_driver() -> 'WebDriver':
    """Return a W3C driver which is generated by a mock response for iOS

    Returns:
        `webdriver.webdriver.WebDriver`: An instance of WebDriver
    """
    response_body_json = json.dumps(
        {
            'sessionId': '1234567890',
            'capabilities': {
                'device': 'iphone',
                'browserName': 'UICatalog',
                'sdkVersion': '11.4',
                'CFBundleIdentifier': 'com.example.apple-samplecode.UICatalog',
            },
        }
    )

    httpretty.register_uri(httpretty.POST, appium_command('/session'), body=response_body_json)

    desired_caps = {
        'platformName': 'iOS',
        'deviceName': 'iPhone Simulator',
        'app': 'path/to/app',
        'automationName': 'XCUITest',
    }

    driver = webdriver.Remote(SERVER_URL_BASE, options=XCUITestOptions().load_capabilities(desired_caps))
    return driver


def ios_w3c_driver_with_extensions(extensions) -> 'WebDriver':
    """Return a W3C driver which is generated by a mock response for iOS

    Returns:
        `webdriver.webdriver.WebDriver`: An instance of WebDriver
    """

    response_body_json = json.dumps(
        {
            'sessionId': '1234567890',
            'capabilities': {
                'device': 'iphone',
                'browserName': 'UICatalog',
                'sdkVersion': '11.4',
                'CFBundleIdentifier': 'com.example.apple-samplecode.UICatalog',
            },
        }
    )

    httpretty.register_uri(httpretty.POST, appium_command('/session'), body=response_body_json)

    desired_caps = {
        'platformName': 'iOS',
        'deviceName': 'iPhone Simulator',
        'app': 'path/to/app',
        'automationName': 'XCUITest',
    }

    driver = webdriver.Remote(SERVER_URL_BASE, options=XCUITestOptions().load_capabilities(desired_caps), extensions=extensions)
    return driver


def flutter_w3c_driver() -> 'WebDriver':
    """Return a W3C driver which is generated by a mock response for Flutter

    Returns:
        `webdriver.webdriver.WebDriver`: An instance of WebDriver
    """

    response_body_json = json.dumps(
        {
            'sessionId': '1234567890',
            'capabilities': {
                'platform': 'LINUX',
                'desired': {
                    'platformName': 'Android',
                    'autoGrantPermissions': True,
                    'flutterSystemPort': 9999,
                    'flutterElementWaitTimeout': 10000,
                    'flutterEnableMockCamera': True,
                    'flutterServerLaunchTimeout': 120000,
                    'automationName': 'FlutterIntegration',
                    'platformVersion': '7.1.1',
                    'deviceName': 'Android Emulator',
                    'app': '/test/apps/ApiDemos-debug.apk',
                },
                'platformName': 'Android',
                'automationName': 'FlutterIntegration',
                'platformVersion': '7.1.1',
                'deviceName': 'emulator-5554',
                'app': '/test/apps/ApiDemos-debug.apk',
                'deviceUDID': 'emulator-5554',
                'appPackage': 'io.appium.android.apis',
                'appWaitPackage': 'io.appium.android.apis',
            },
        }
    )

    httpretty.register_uri(httpretty.POST, appium_command('/session'), body=response_body_json)

    desired_caps = {
        'platformName': 'Android',
        'deviceName': 'Android Emulator',
        'app': 'path/to/app',
        'automationName': 'FlutterIntegration',
    }

    driver = webdriver.Remote(SERVER_URL_BASE, options=UiAutomator2Options().load_capabilities(desired_caps))
    return driver


def get_httpretty_request_body(request: 'HTTPrettyRequestEmpty') -> Dict[str, Any]:
    """Returns utf-8 decoded request body"""
    return json.loads(request.body.decode('utf-8'))
